package com.youlu.campus.admin.community.service.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.activity.service.ActivityLotteryConfigService;
import com.youlu.campus.admin.auth.entity.SystemRole;
import com.youlu.campus.admin.auth.entity.SystemUser;
import com.youlu.campus.admin.auth.service.RoleService;
import com.youlu.campus.admin.community.dto.ActivityOnTopRequest;
import com.youlu.campus.admin.community.dto.ActivityQueryRequest;
import com.youlu.campus.admin.community.dto.ActivityResponse;
import com.youlu.campus.admin.community.dto.ActivitySignQueryRequest;
import com.youlu.campus.admin.community.service.ActivityService;
import com.youlu.campus.admin.utils.AuthUtils;
import com.youlu.campus.admin.utils.JsonUtil;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.common.utils.ShotUrlUtil;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.ActivityCaOrg;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityPointConfig;
import com.youlu.campus.entity.ActivityQaInfo;
import com.youlu.campus.entity.ActivitySimulationData;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.ActivityTaskRule;
import com.youlu.campus.entity.DailyLearning;
import com.youlu.campus.entity.HuoLinkerInfo;
import com.youlu.campus.entity.PlatformConfig;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserActivityFootPrint;
import com.youlu.campus.entity.UserActivityPointDetail;
import com.youlu.campus.service.ranking.entity.UserActivityPointRanking;
import com.youlu.campus.entity.UserActivityTopRecord;
import com.youlu.campus.entity.UserBlackList;
import com.youlu.campus.entity.UserInviteRecord;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.UserParticipateActivityTaskInfo;
import com.youlu.campus.entity.UserQaInfo;
import com.youlu.campus.entity.UserRankBlackList;
import com.youlu.campus.entity.VO.req.ActivityFootPrintQueryVO;
import com.youlu.campus.entity.VO.req.ActivityOrgReq;
import com.youlu.campus.entity.VO.req.UserDataPermissionUpdateVO;
import com.youlu.campus.entity.activity.ActivityTaskBizType;
import com.youlu.campus.entity.activity.ActivityTypeEnum;
import com.youlu.campus.entity.commission.UserParticipateDistributorChannelInfo;
import com.youlu.campus.entity.data.ActivityUserStatistics;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.entity.jinshuju.JinUserParticipate;
import com.youlu.campus.entity.system.UserDataPermission;
import com.youlu.campus.service.activity.ActivityPointConfigService;
import com.youlu.campus.service.activity.ActivityTaskRuleService;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.activity.UserParticipateActivityInfoService;
import com.youlu.campus.service.base.BaseService;
import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.commission.UserParticipateDistributorChannelInfoService;
import com.youlu.campus.service.data.ActivityUserStatisticsService;
import com.youlu.campus.service.data.impl.UvPvService;
import com.youlu.campus.service.linker.HuoLinkerInfoService;
import com.youlu.campus.service.platform.PlatformConfigService;
import com.youlu.campus.service.qa.UserQaInfoService;
import com.youlu.campus.service.rank.RankBaseService;
import com.youlu.campus.service.rank.UserRankListService;
import com.youlu.campus.service.ranking.UserActivityPointDetailService;
import com.youlu.campus.service.ranking.UserActivityPointRankingProvinceService;
import com.youlu.campus.service.ranking.UserActivityPointRankingService;
import com.youlu.campus.service.ranking.UserRankBlackListService;
import com.youlu.campus.service.system.UserDataPermissionService;
import com.youlu.campus.service.university.UniversityInfoService;
import com.youlu.campus.service.visitor.UserBlackListService;
import com.youlu.campus.service.visitor.VisitorUserService;
import com.yuelin.infrastructure.quantum.common.QResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 活动接口实现类
 *
 * @author: zhuhuaiqi
 * @date: 2020/12/11 17:17
 */
@Slf4j
@Service("activityService")
public class ActivityServiceImpl extends BaseService implements ActivityService {

    @Value("${sys.activity.page}")
    private String acPage;
    @Autowired
    private com.youlu.campus.service.activity.ActivityService activityServiceS;
    @Autowired
    private ActivityTaskRuleService activityTaskRuleService;
    @Autowired
    private VisitorUserService visitorUserService;
    @Autowired
    private CacheActivityService cacheActivityService;
    @Autowired
    private UserDataPermissionService userDataPermissionService;
    @Autowired
    private ActivityUserStatisticsService activityUserStatisticsService;
    @Autowired
    private UniversityInfoService universityInfoService;
    @Autowired
    private UserBlackListService blackListService;
    @Autowired
    private PlatformConfigService platformConfigService;
    @Lazy
    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;


    private String activityProgressUrl = "/h4/index.html#/pages/activity-schedule?activityId=%s&theme=%s&appId=%s" +
            "&authorizeMode=%s";
    private String activityUrl = "/index.html?#/pages/activity-detial?activityId=%s&appId=%s&theme=%s" +
            "&authorizeMode=%s";
    private String activityUrl2 = "index.html?#/pages/activity-detial?activityId=%s&appId=%s&theme=%s" +
            "&authorizeMode=%s";
    private String activityVoteUrl = "/v5/index.html?#/pages/activity-detial?activityId=%s&appId=%s&theme=%s" +
            "&authorizeMode=%s";
    /**
     * 新竞赛活动
     */
    private String activityContestPluUrl = "/c5/index.html?#/?appId=%s&activityId=%s&theme=%s";
    /**
     * 新竞赛活动进度链接
     */
    private String activityContestPlusProgressUrl = "/c5/index.html?#/pages/share-invitation?appId=%s&activityId=%s" +
            "&theme=&s";

    private String activityContestUrl = "/contest-h5/index.html?a=a#/pages/home?appId=%s&activityId=%s";
    /**
     * 收款链接
     */
    private String activityPayUrl = "/h5/#/pages/activity-reward?activityId=%s&appId=%s&theme=%s&authorizeMode=%s";

    @Autowired
    private HuoLinkerInfoService huoLinkerInfoService;
    @Value("${sys.constentActivity:61834be460d5e86411b654a5}")
    private String constentActivity;

    @Autowired
    private UvPvService uvPvService;
    @Autowired
    private UserQaInfoService userQaInfoService;
    @Autowired
    private UserActivityPointDetailService userActivityPointDetailService;
    @Autowired
    private UserActivityPointRankingService userActivityPointRankingService;
    @Autowired
    private ActivityPointConfigService activityPointConfigService;
    @Autowired
    private UserRankBlackListService userRankBlackListService;
    @Autowired
    private UserRankListService userRankListService;
    @Autowired
    private ActivityTaskService activityTaskService;
    @Autowired
    private RankBaseService rankBaseService;
    @Autowired
    private UserActivityPointRankingProvinceService userActivityPointRankingProvinceService;

    @Lazy
    @Autowired
    private UserParticipateDistributorChannelInfoService userParticipateDistributorChannelInfoService;

    private final static String MOBILE_REGEX = "(\\d{3})\\d{4}(\\d{4})";

    @Autowired
    private ActivityLotteryConfigService activityLotteryConfigService;

    @Value("${spring.profiles.active}")
    private String env;

    @Override
    public List<ActivityInfo> findActiveActivities() {
        Date currentTime = new Date();
        Query query = Query.query(Criteria.where("startTime").lte(currentTime))
                .addCriteria(Criteria.where("endTime").gte(currentTime));
        List<ActivityInfo> activityInfos = mongoTemplate.find(query, ActivityInfo.class);
        return activityInfos;
    }

    @Override
    public void updateRandomInitJoinNum(String id, long newValue) {
        // 创建查询条件：根据ID查询
        Query query = Query.query(Criteria.where("_id").is(id));

        // 创建更新操作：设置randomInitjum字段的新值
        Update update = new Update();
        update.set("randomInitJoinNum", newValue);

        // 执行更新操作（只更新匹配到的第一条记录）
        mongoTemplate.updateFirst(query, update, ActivityInfo.class);
    }

    @Override
    public boolean createActivity(ActivityInfo request) {
        log.info("createActivity 新增活动信息开始，参数:{}", JsonUtil.toJSON(request));
        if (Objects.isNull(request)) {
            log.error(":>>> 创建活动参数错误:对象为空");
            throw new BusinessException("活动参数为空");
        }
        //验证 请求参数
        verifyActivityParam(request);
        //验证是否重名
        Query query = new Query().addCriteria(Criteria.where("name").is(request.getName()));
        boolean exist = mongoTemplate.exists(query, ActivityInfo.class);
        if (exist) {
            log.error("createActivity 活动已经存在:{}", request.getName());
            throw new BusinessException("活动名称重复，请修改");
        }
        // 检查营销活动
        ActivityInfo activityInfo = mapperFacade.map(request, ActivityInfo.class);
        activityInfo.setCreatedTime(new Date());
        activityInfo.setId(null);
        activityInfo.setPriority(request.getPriority());
        activityInfo.setRewardValueUnitDesc(request.getRewardValueAlias());
        activityInfo.setOrderTips(request.getReceiveAddressTips());
        if ("prod".equals(env)) {
            activityInfo.setWechatAppId("wx911ab7f9d5bb5aa0");
        } else {
            activityInfo.setWechatAppId("wxbaba4b2c54e8881a");
        }
        //新增活动
        activityInfo = mongoTemplate.insert(activityInfo);
        log.info("createActivity 新增活动信息结束:{}", JSON.toJSONString(activityInfo));
        //新增分享任务
        addActivityTaskInfo(activityInfo, ActivityTaskBizType.INVITE);

        //新增 线下承办单位活动
        if (Boolean.TRUE.equals(activityInfo.getHasOrganizer())) {
            addActivityTaskInfo(activityInfo, ActivityTaskBizType.ORGANIZER);
        }
        //新增 线下志愿服务
        if (Boolean.TRUE.equals(activityInfo.getHasOffLine())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.OFF_LINE);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.OFF_LINE, taskInfo, 0D);
        }
        //新增 提交感悟 任务
        if (Boolean.TRUE.equals(activityInfo.getSubmitGanWu())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.SHOW_STYLE);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.SHOW_STYLE, taskInfo, 0D);
        }
        //新增 学习签到 任务
        if (Boolean.TRUE.equals(activityInfo.getHasSignIn())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.LEARNING);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.LEARNING, taskInfo, 0D);
        }
        //新增 每日知识挑战 任务
        if (Boolean.TRUE.equals(activityInfo.getHasKnowleageChallage())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.KNOWLEDGE_CHALLENGE);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.KNOWLEDGE_CHALLENGE, taskInfo, 0D);
        }
        //新增 实践行动 任务
        if (Boolean.TRUE.equals(activityInfo.getHasPraxis())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.PRAXIS);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.PRAXIS, taskInfo, 0D);
        }
        //新增 作品征集 任务
        if (Boolean.TRUE.equals(activityInfo.getHasWorkCollection())) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.WORK_COLLECTION);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.WORK_COLLECTION, taskInfo, 0D);
        }
        //新增 看视频任务
        if (activityInfo.getHasVideo()) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.VIDEO);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.VIDEO, taskInfo, 0D);
        }
        //新增 答题得证书 任务
        if (activityInfo.getHasQa()) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.QA);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.QA, taskInfo, 0D);
        }
        //新增 添加QQ群 任务
        if (activityInfo.getHasJoinQqGroup()) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.JOIN_QQ_GROUP);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.JOIN_QQ_GROUP, taskInfo, 0D);
        }
        //新增 外部任务
        if (activityInfo.getHasOuterTask()) {
            //创建任务
            ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.OUTER_TASK);
            //创建任务规则
            addTaskInfoRule(activityInfo, TaskBizType.OUTER_TASK, taskInfo, 0D);
        }
        //新增 订阅消息
        if (Boolean.TRUE.equals(activityInfo.getHasSubscription())) {
            //创建任务
            addActivityTaskInfo(activityInfo, ActivityTaskBizType.SUBSCRIPTION);
        }
        //新增 报名任务 //创建任务
        ActivityTaskInfo taskInfo = addActivityTaskInfo(activityInfo, ActivityTaskBizType.JOIN_ACTIVITY);
        //新增 报名任务规则
        addTaskInfoRule(activityInfo, TaskBizType.JOIN_ACTIVITY, taskInfo, 10D);

        try {
            //同步活动信息到统计系统
            ActivityQaInfo activityQaInfo = new ActivityQaInfo();
            activityQaInfo.setActivityId(activityInfo.getId());
            activityQaInfo.setActivityName(activityInfo.getName());
            activityQaInfo.setStartTime(activityInfo.getStartTime());
            activityQaInfo.setEndTime(activityInfo.getEndTime());
            uvPvService.doActivityInfo(activityQaInfo);
        } catch (Exception e) {
            log.error("同步活动信息错误:{}", e);
        }
        //添加活动 用户权限
        List<String> userIds = new ArrayList<>();
        userIds.add(request.getCreatorId());
        userDataPermissionService.addUserDataPermission(activityInfo.getId(), userIds);
        ActivityPointConfig config = activityPointConfigService.findByActivityId(activityInfo.getId());
        if (Objects.isNull(config)) {
            config = new ActivityPointConfig();
            config.setActivityId(activityInfo.getId());
            config.setCreatedTime(new Date());
            config.getRules().put("recieve-paper-ca", 2000);
            config.getRules().put("recieve-digit-ca", 500);
            activityPointConfigService.create(config);
        }
        activityTaskRuleService.saveOrUpdateQa(activityInfo.getId(), request.getAfterQaAddPoint());
        return true;
    }

    /**
     * 创建活动任务规则
     *
     * @param activityInfo
     * @param offLine
     * @param taskInfo
     * @param points
     */
    private void addTaskInfoRule(ActivityInfo activityInfo, TaskBizType offLine, ActivityTaskInfo taskInfo, double points) {
        ActivityTaskRule rule = new ActivityTaskRule();
        rule.setActivityId(activityInfo.getId());
        rule.setBizType(offLine.name());
        rule.setTaskId(taskInfo.getId());
        rule.setCreatedTime(new Date());
        rule.setPoints(points);
        rule.setThreshold(1);
        mongoTemplate.insert(rule);
    }

    /**
     * 创建活动任务
     *
     * @param activityInfo
     * @param taskBizType
     * @return
     */
    private ActivityTaskInfo addActivityTaskInfo(ActivityInfo activityInfo, ActivityTaskBizType taskBizType) {
        ActivityTaskInfo taskInfo = new ActivityTaskInfo();
        taskInfo.setActivityId(activityInfo.getId());
        taskInfo.setTaskBizType(taskBizType.getType());
        taskInfo.setCreatedTime(new Date());
        if (ActivityTaskBizType.JOIN_QQ_GROUP.equals(taskBizType)) {
            taskInfo.setName(taskBizType.getDesc());
        } else {
            taskInfo.setName(activityInfo.getName() + "-" + taskBizType.getDesc());
        }
        if (ActivityTaskBizType.JOIN_ACTIVITY.equals(taskBizType) || ActivityTaskBizType.QA.equals(taskBizType)) {
            taskInfo.setOpened(false);
        } else {
            taskInfo.setOpened(true);
        }
        ActivityTaskInfo insert = mongoTemplate.insert(taskInfo);
        return insert;
    }

    /**
     * 验证请求参数
     *
     * @param request
     */
    private void verifyActivityParam(ActivityInfo request) {
        // 获取活动类型枚举
        ActivityTypeEnum activityType = ActivityTypeEnum.getByType(request.getType());
        if (activityType == null) {
            throw new BusinessException("不支持的活动类型");
        }
        List<String> msg = new ArrayList<>();
        if (StringUtils.isBlank(request.getName())) {
            msg.add("活动名称");
        }
        if (request.getPaymentSmsEnabled() && StringUtils.isBlank(request.getSmsActivityName())) {
            msg.add("须知信息");
        }
        if (ActivityTypeEnum.BEFORE.equals(activityType)) {
            if (StringUtils.isBlank(request.getMustKnow())) {
                msg.add("须知信息");
            }
            if (StringUtils.isBlank(request.getImageUrl())) {
                msg.add("活动封面");
            }
            if (StringUtils.isBlank(request.getDetail())) {
                msg.add("活动详情");
            }
            if (Objects.isNull(request.getStartTime())) {
                msg.add("开始时间");
            }
            if (Objects.isNull(request.getEndTime())) {
                msg.add("结束时间");
            }
            if (Objects.isNull(request.getIncentivesStartTime())) {
                msg.add("奖励发放开始时间");
            }
            if (Objects.isNull(request.getIncentivesEndTime())) {
                msg.add("奖励发放结束时间");
            }
            if (StringUtils.isBlank(request.getShareName())) {
                msg.add("分享名称");
            }
            if (StringUtils.isBlank(request.getShareImageUrl())) {
                msg.add("分享主图片");
            }
            if (request.getReceiveCaValue() > 0 && StringUtils.isBlank(request.getReceiveCaErrorTips())) {
                msg.add("领取电子证书条件不满足错误提示");
            }
        }
        if (ActivityTypeEnum.VOTE.equals(activityType)) {
            if (StringUtils.isBlank(request.getUserRankName())) {
                msg.add("用户榜的名字");
            }
            if (StringUtils.isBlank(request.getUserRankSubTile())) {
                msg.add("用户榜的副标题");
            }
            if (StringUtils.isBlank(request.getOrgTypeId())) {
                msg.add("组织类型");
            }
            if (StringUtils.isBlank(request.getReceiveCertTitle())) {
                msg.add("领取证书标题");
            }
            if (StringUtils.isBlank(request.getReceiveCertCondition())) {
                msg.add("领取证书条件");
            }
            if (!canBindVoteActivity(null, request.getOrgTypeId())) {
                throw new BusinessException("组织绑定其他活动了");
            }
        }

        if (ActivityTypeEnum.VIDEO.equals(activityType)) {
            if (StringUtils.isBlank(request.getWxMiniOfficialQrcode())) {
                msg.add("小程序官方社群码");
            }
            if (StringUtils.isBlank(request.getCourseId())) {
                msg.add("课程");
            }
            if (StringUtils.isBlank(request.getId()) && !canBindCourseActivity(null, request.getCourseId())) {
                throw new BusinessException("课程绑定其他活动了");
            }
        }

        if (ActivityTypeEnum.QIMOBANG_VIDEO.equals(activityType)) {
            if (StringUtils.isBlank(request.getCourseId())) {
                msg.add("课程");
            }
            if (StringUtils.isBlank(request.getId()) && !canBindCourseActivity(null, request.getCourseId())) {
                throw new BusinessException("课程绑定其他活动了");
            }
        }

        if (ActivityTypeEnum.THIRD_VIDEO.equals(activityType)) {
            if (StringUtils.isBlank(request.getCourseId())) {
                msg.add("课程");
            }
            if (StringUtils.isBlank(request.getThirdCourseUrl())) {
                msg.add("第三方课程连接");
            }
        }
        if (!CollectionUtils.isEmpty(msg)) {
            String errorMessage = String.join(",", msg);
            log.error("createActivityCheckParam 创建活动参数错误:{}", errorMessage);
            throw new BusinessException("请填写缺失信息:" + errorMessage);
        }
    }

    public boolean canBindCourseActivity(ActivityInfo activityInfo, String courseId) {
        // 插入
        if (activityInfo == null) {
            Query query = new Query();
            query.addCriteria(Criteria.where("courseId").in(courseId));
            ActivityInfo info = mongoTemplate.findOne(query, ActivityInfo.class);
            return info == null;
        }
        // 修改
        return activityInfo.getCourseId().equals(courseId);
    }

    public boolean canBindVoteActivity(ActivityInfo activityInfo, String orgTypeId) {
        // 插入
        if (activityInfo == null) {
            Query query = new Query();
            query.addCriteria(Criteria.where("orgTypeId").in(orgTypeId));
            ActivityInfo info = mongoTemplate.findOne(query, ActivityInfo.class);
            return info == null;
        }
        // 修改
        return activityInfo.getOrgTypeId().equals(orgTypeId);
    }

    @Override
    public boolean updateActivity(ActivityInfo request) {
        log.info("修改活动信息开始，参数:{}", JsonUtil.toJSON(request));
        //验证参数
        verifyActivityParam(request);

        ActivityInfo activityInfo = findOne(request.getId());
        //判断绑定课程 是否修改
        if (StringUtils.isNotBlank(request.getCourseId()) && !activityInfo.getCourseId().equals(request.getCourseId())) {
            Query query = new Query();
            query.addCriteria(Criteria.where("courseId").in(request.getCourseId()));
            ActivityInfo info = mongoTemplate.findOne(query, ActivityInfo.class);
            if (info != null && !info.getId().equals(request.getId())) {
                throw new BusinessException("课程绑定其他活动了");
            }
        }
        mapperFacade.map(request, activityInfo);
        if (Boolean.TRUE.equals(request.getQaLimit()) || Objects.isNull(request.getQaLimit())) {
            activityInfo.setQaLimit(false);
        }
        activityInfo.setOrderTips(request.getReceiveAddressTips());
        activityInfo.setPriority(request.getPriority());
        activityInfo.setRewardValueUnitDesc(request.getRewardValueAlias());
        activityInfo.setUpdatedTime(new Date());
        mongoTemplate.save(activityInfo);
        if (Boolean.TRUE.equals(activityInfo.getHasOrganizer())) {
            initTaskInfoByUpdate(activityInfo, ActivityTaskBizType.ORGANIZER);
        } else {
            removeTask(request.getId(), TaskBizType.ORGANIZER);
            removeTaskRule(request.getId(), TaskBizType.ORGANIZER.name());
        }
        if (Boolean.TRUE.equals(request.getHasOffLine())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.OFF_LINE, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.OFF_LINE);
            removeTaskRule(request.getId(), TaskBizType.OFF_LINE.name());
        }
        if (Boolean.TRUE.equals(request.getSubmitGanWu())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.SHOW_STYLE, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.SHOW_STYLE);
            removeTaskRule(request.getId(), TaskBizType.SHOW_STYLE.name());
        }
        if (Boolean.TRUE.equals(request.getHasWorkCollection())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.WORK_COLLECTION, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.WORK_COLLECTION);
            removeTaskRule(request.getId(), TaskBizType.WORK_COLLECTION.name());
        }
        if (Boolean.TRUE.equals(request.getHasPraxis())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.PRAXIS, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.PRAXIS);
            removeTaskRule(request.getId(), TaskBizType.PRAXIS.name());
        }
        if (Boolean.TRUE.equals(request.getHasKnowleageChallage())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.KNOWLEDGE_CHALLENGE, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.KNOWLEDGE_CHALLENGE);
            removeTaskRule(request.getId(), TaskBizType.KNOWLEDGE_CHALLENGE.name());
        }
        if (Boolean.TRUE.equals(request.getHasSignIn())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.LEARNING, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.LEARNING);
            removeTaskRule(request.getId(), TaskBizType.LEARNING.name());
        }
        if (Boolean.TRUE.equals(request.getDoQaHasCa())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.QA, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.QA);
            removeTaskRule(request.getId(), TaskBizType.QA.name());
        }
        if (Boolean.TRUE.equals(request.getHasJoinQqGroup())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.JOIN_QQ_GROUP, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.JOIN_QQ_GROUP);
            removeTaskRule(request.getId(), TaskBizType.JOIN_QQ_GROUP.name());
        }
        if (Boolean.TRUE.equals(request.getHasOuterTask())) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.OUTER_TASK, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.OUTER_TASK);
            removeTaskRule(request.getId(), TaskBizType.OUTER_TASK.name());
        }
        if (request.getHasVideo()) {
            initTaskInfoAndRuleByUpdate(activityInfo, ActivityTaskBizType.VIDEO, 0D);
        } else {
            removeTask(request.getId(), TaskBizType.VIDEO);
            removeTaskRule(request.getId(), TaskBizType.VIDEO.name());
        }
        if (Boolean.TRUE.equals(activityInfo.getHasSubscription())) {
            initTaskInfoByUpdate(activityInfo, ActivityTaskBizType.SUBSCRIPTION);
        } else {
            removeTask(request.getId(), TaskBizType.SUBSCRIPTION);
            removeTaskRule(request.getId(), TaskBizType.SUBSCRIPTION.name());
        }
        try {
            //同步活动信息到统计系统
            ActivityQaInfo activityQaInfo = new ActivityQaInfo();
            activityQaInfo.setActivityId(activityInfo.getId());
            activityQaInfo.setActivityName(activityInfo.getName());
            activityQaInfo.setStartTime(activityInfo.getStartTime());
            activityQaInfo.setEndTime(activityInfo.getEndTime());
            uvPvService.doActivityInfo(activityQaInfo);
        } catch (Exception e) {
            log.error("同步活动信息错误:{}", e);
        }
        activityTaskRuleService.saveOrUpdateQa(activityInfo.getId(), request.getAfterQaAddPoint());
        cacheActivityService.put(activityInfo);
        //修改抽奖活动贡献值别名
        activityLotteryConfigService.updateInvitePoints(activityInfo.getId());
        log.info("修改活动信息结束");
        return true;
    }

    private void initTaskInfoByUpdate(ActivityInfo request, ActivityTaskBizType activityTaskBizType) {
        Query queryTask = new Query().addCriteria(Criteria.where("activityId").is(request.getId())
                .and("taskBizType").is(activityTaskBizType.getType()));
        boolean exist = mongoTemplate.exists(queryTask, ActivityTaskInfo.class);
        if (!exist) {
            addActivityTaskInfo(request, activityTaskBizType);
        }
    }

    private void initTaskInfoAndRuleByUpdate(ActivityInfo request, ActivityTaskBizType activityTaskBizType, Double point) {
        Query queryTask = new Query().addCriteria(Criteria.where("activityId").is(request.getId())
                .and("taskBizType").is(activityTaskBizType.getType()));
        boolean exist = mongoTemplate.exists(queryTask, ActivityTaskInfo.class);
        if (!exist) {
            ActivityTaskInfo taskInfo = addActivityTaskInfo(request, activityTaskBizType);
            addTaskInfoRule(request, activityTaskBizType.getType(), taskInfo, point);

        }
    }

    private void removeTask(String activityId, TaskBizType taskBizType) {
        Query queryTask =
                new Query().addCriteria(Criteria.where("activityId").is(activityId).and("taskBizType").is(taskBizType));
        this.mongoTemplate.remove(queryTask, ActivityTaskInfo.class);
    }

    private void removeTaskRule(String activityId, String bizType) {
        Query queryTask =
                new Query().addCriteria(Criteria.where("activityId").is(activityId).and("bizType").is(bizType));
        this.mongoTemplate.remove(queryTask, ActivityTaskRule.class);
    }

    @Override
    public boolean deleteActivity(String id) {
        log.info("删除活动信息开始，id:{}", id);

        ActivityInfo activityInfo = findOne(id);
        if (Objects.isNull(activityInfo) || Objects.isNull(activityInfo.getStartTime())) {
            log.info(":>>> 删除活动信息活动不存在，id:{}", id);
            return false;
        }
        if (activityInfo.getStartTime().before(new Date())) {
            log.info(":>>> 活动已经开始不能删除，id:{}", id);
            return false;
        }
        activityInfo.setDeleted(true);
        activityInfo.setUpdatedTime(new Date());
        mongoTemplate.save(activityInfo);
        cacheActivityService.remove(id);
        log.info("删除活动信息结束");
        return true;
    }

    @Override
    public Page<ActivityResponse> activityList(ActivityQueryRequest request) {
        log.info("查询活动信息列表，参数:{}", JsonUtil.toJSON(request));
        //page 对象
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());

        Query query = getActivityQuery(request, new Query());
        boolean hasUserId = StringUtils.isNotBlank(request.getUserId());

        List<String> aclAidList = new ArrayList<>();

        Criteria criteria = new Criteria();
        if (StringUtils.isNotEmpty(request.getId())) {
            criteria.andOperator(Criteria.where("id").is(request.getId()));
            aclAidList.add(request.getId());
        } else if (hasUserId) {
            UserDataPermission req = new UserDataPermission();
            req.setUserId(request.getUserId());
            List<UserDataPermission> datas = userDataPermissionService.list(req);
            if (!CollectionUtils.isEmpty(datas) && !CollectionUtils.isEmpty(datas.get(0).getActivityId())) {
                UserDataPermission userDataPermission = datas.get(0);
                log.info(":>>> 用户:{} 的数据权限权限配置:{}", request.getUserId(), JSON.toJSON(userDataPermission.getActivityId()));
                aclAidList = datas.get(0).getActivityId();
            }
            criteria.andOperator(Criteria.where("id").in(aclAidList));
        }
        if (aclAidList.size() == 0) {
            return PageableExecutionUtils.getPage(Arrays.asList(), pageRequest, () -> 0);
        }
        query.addCriteria(criteria);
        Long count = mongoTemplate.count(query, ActivityInfo.class);
        if (count == 0) {
            return PageableExecutionUtils.getPage(Arrays.asList(), pageRequest, () -> 0);
        }
        List<ActivityInfo> activityInfos = new ArrayList<>();
        int totalTopNum = 0;
        if (hasUserId) {
            // 置顶活动列表
            List<ActivityInfo> topActivityList = getTopActivityList(request, aclAidList);
            totalTopNum = topActivityList.size();
            if (totalTopNum > 0) {
                // 添加置顶活动分页
                int skip = (request.getPage() - 1) * request.getPageSize();
                List<ActivityInfo> topActivityInfo = topActivityList.stream().skip(skip).limit(request.getPageSize()).collect(Collectors.toList());
                activityInfos.addAll(topActivityInfo);
                // 条件中除去置顶活动列表
                List<String> topAidList = topActivityList.stream().map(ActivityInfo::getId).distinct().collect(Collectors.toList());
                criteria.and("id").nin(topAidList);
            }
        }
        int start = (request.getPage() - 1) * request.getPageSize();
        int end = start + request.getPageSize();
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        if (totalTopNum < start) {
            query.skip(start - totalTopNum).limit(request.getPageSize());
            activityInfos.addAll(mongoTemplate.find(query, ActivityInfo.class));
        }
        if (totalTopNum >= start && totalTopNum < end) {
            query.skip(0).limit(end - totalTopNum);
            activityInfos.addAll(mongoTemplate.find(query, ActivityInfo.class));
        }
        List<ActivityResponse> list = activityInfos.stream().map(activityInfo -> {
            ActivityResponse response = mapperFacade.map(activityInfo, ActivityResponse.class);
            response.setUrl(acPage + response.getId());
            if ("65b8ac2e4071b66f31738851".equals(response.getId())) {
                response.setUserCount(1942904L);
            } else {
                response.setUserCount(getUsetCount(response.getId(), request.getUserId()));
            }
            if (StringUtils.isNotBlank(activityInfo.getWechatAppId())) {
                String wechatUrl = "";
                String wechatProgressUrl = "";
                if ("contest-plus".equals(activityInfo.getType())) {
                    wechatUrl = String.format(this.activityContestPluUrl, activityInfo.getWechatAppId(),
                            activityInfo.getId(), activityInfo.getThemeColor());
                    wechatProgressUrl = String.format(this.activityContestPluUrl, activityInfo.getWechatAppId(),
                            activityInfo.getId(), activityInfo.getThemeColor());
                } else if ("vote".equals(activityInfo.getType())) {
                    wechatUrl = String.format(this.activityVoteUrl, activityInfo.getId(), activityInfo.getWechatAppId(),
                            activityInfo.getThemeColor(), activityInfo.getAuthorizeMode());
                } else {
                    wechatUrl = String.format(this.activityUrl2, activityInfo.getId(), activityInfo.getWechatAppId(),
                            activityInfo.getThemeColor(), activityInfo.getAuthorizeMode());
                    wechatProgressUrl = String.format(this.activityProgressUrl, activityInfo.getId(),
                            activityInfo.getThemeColor(), activityInfo.getWechatAppId(),
                            activityInfo.getAuthorizeMode());
                }

                String domain = "";
                String catalogue = "";
                String type = "";
                if (constentActivity.contains(activityInfo.getId())) {
                    wechatUrl = String.format(this.activityContestUrl, activityInfo.getWechatAppId(),
                            activityInfo.getId());
                    domain = platformConfigService.getContestBizFrontDomain();
                    catalogue = platformConfigService.getContestCatalogue();
                    type = "C";
                    if (wechatUrl.contains("/h5/")) {
                        wechatUrl = wechatUrl.replace("/h5/", "/contest-h5/");
                    }
                    if (wechatProgressUrl.contains("/h5/")) {
                        wechatProgressUrl = wechatProgressUrl.replace("/h5/", "/contest-h5/");
                    }
                } else {
                    domain = platformConfigService.getBizFrontDomain();
                    if ("contest-plus".equals(activityInfo.getType())) {
                        catalogue = platformConfigService.getContestPlusCatalogue();
                        type = "C-PLUS";
                    } else {
                        catalogue = platformConfigService.getCatalogue();
                        type = "A";
                    }

                }
                log.info(":>>> 活动:{},domain:{},catalogue:{},type:{}", activityInfo.getName(), domain, catalogue, type);
                response.setWechatH5Url(domain + catalogue + platformConfigService.replaceActiveCatalogue(wechatUrl, catalogue,
                        type));
                String payUrl = String.format(this.activityPayUrl, activityInfo.getId(),
                        activityInfo.getWechatAppId(), activityInfo.getThemeColor(), activityInfo.getAuthorizeMode());
                response.setWechatPayUrl(platformConfigService.getBizFrontDomain() + payUrl);
                response.setWechatProgressUrl(domain + platformConfigService.replaceActiveCatalogue(wechatProgressUrl
                        , catalogue, type));
            }
            if (StringUtils.isNotBlank(activityInfo.getQqAppId())) {
                String qqUrl = String.format(this.activityUrl, activityInfo.getId(), activityInfo.getQqAppId(),
                        activityInfo.getThemeColor(), "qq");
                response.setQqH5Url(platformConfigService.getQQBizFrontDomain() + qqUrl);
            }
            ActivityUserStatistics a = activityUserStatisticsService.findByActivityId(response.getId());
            if (Objects.nonNull(a)) {
                response.setNewUserCount(a.getNewUserCount());
                response.setOldUserCount(a.getOldUserCount());
            }
            response.setActivityCaOrgSet(activityInfo.getActivityCaOrgSet());
            response.setQqMiniUrl(String.format("/pages/activity/detail?activityId=%s", activityInfo.getId()));
            if ("wx-mini-dreambeat-contest".equals(activityInfo.getType()) || "publicity".equals(activityInfo.getType())) {
                response.setWechatMiniUrl(String.format("/pages/contest/detail?activityId=%s", activityInfo.getId()));
            } else if ("recruitment".equals(activityInfo.getType())) {
                response.setWechatMiniUrl(String.format("/pages/recruitment?activityId=%s", activityInfo.getId()));
            } else if ("daka".equals(activityInfo.getType())) {
                response.setWechatMiniUrl(String.format("/pages/check-in/detail?activityId=%s", activityInfo.getId()));
            } else if ("timetable".equals(activityInfo.getType())) {
                response.setWechatMiniUrl(String.format("/pages/tabbar/tabbar?activityId=%s", activityInfo.getId()));
            } else if ("jinshuju".equals(activityInfo.getType())) {
                PlatformConfig platformConfig = platformConfigService.find();
                String cate = platformConfig.getJinCatalogue();
                long time = System.currentTimeMillis();
                String domain = platformConfig.getJinBizFrontDomain();
                response.setJinJoinUrl(domain + cate + "/index.html?a=1#/pages/index?scope=snsapi_base&activityId=" + activityInfo.getId() + "&t=" + time + "&appId=" + activityInfo.getWechatAppId());
                response.setJinSearchUrl(domain + cate + "/index.html?a=1#/pages/search?scope=snsapi_base&activityId=" + activityInfo.getId() + "&t=" + time + "&appId=" + activityInfo.getWechatAppId());
            } else if ("continuous-daka".equals(activityInfo.getType())) {
                response.setWechatMiniUrl(String.format("/pages/continuous-check-in/detail?activityId=%s", activityInfo.getId()));
            } else {
                response.setWechatMiniUrl(String.format("/pages/activity/detail?activityId=%s", activityInfo.getId()));

            }
            return response;
        }).collect(Collectors.toList());
        log.info(":>>> 活动列表:{}", list == null ? 0 : list.size());
        Long finalCount = count;
        return PageableExecutionUtils.getPage(list, pageRequest, () -> finalCount);
    }

    public List<ActivityInfo> getTopActivityList(ActivityQueryRequest request, List<String> aclAidList) {
        // 搜索匹配条件的活动
        Query topActivityQuery = getActivityQuery(request, new Query());
        topActivityQuery.addCriteria(Criteria.where("id").in(aclAidList));
        List<ActivityInfo> topActivityList = mongoTemplate.find(topActivityQuery, ActivityInfo.class);
        List<String> searchAidList = topActivityList.stream().map(ActivityInfo::getId).collect(Collectors.toList());
        // 置顶活动活动列表
        List<UserActivityTopRecord> topList = getActivityTopRecordList(request.getUserId(), searchAidList);
        Map<String, ActivityInfo> topAcMap = topActivityList.stream().collect(Collectors.toMap(ActivityInfo::getId, Function.identity(), (o1, o2) -> o2));
        // 按照优先级排序置顶活动
        List<ActivityInfo> activityInfos = topList.stream().filter(record -> topAcMap.get(record.getActivityId()) != null)
                .map(record -> {
                    ActivityInfo activityInfo = topAcMap.get(record.getActivityId());
                    activityInfo.setOnTop(record.getOnTop());
                    return activityInfo;
                }).collect(Collectors.toList());
        return activityInfos;
    }

    public Query getActivityQuery(ActivityQueryRequest request, Query query) {
        if (StringUtils.isNotBlank(request.getName())) {
            Pattern pattern = Pattern.compile("^.*" + request.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(pattern));
        }
        if (StringUtils.isNotBlank(request.getType())) {
            query.addCriteria(Criteria.where("type").is(request.getType()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        return query;
    }

    @Override
    public boolean activityOnTop(ActivityOnTopRequest request) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(request.getUserId()).and("activityId").is(request.getActivityId()));
        UserActivityTopRecord record = mongoTemplate.findOne(query, UserActivityTopRecord.class);
        if (record == null) {
            // 获取最大优先级
            int priority = getMaxPriority(request.getUserId()) + 1;
            record = new UserActivityTopRecord();
            record.setOnTop(true);
            record.setUserId(request.getUserId());
            record.setActivityId(request.getActivityId());
            record.setPriority(priority);
            record.setCreatedTime(new Date());
            record.setUpdatedTime(new Date());
            mongoTemplate.insert(record);
            return true;
        }
        Update update = new Update();
        if (record.getOnTop()) {
            update.set("onTop", false);
            update.set("priority", 0);
        } else {
            // 获取最大优先级
            int priority = getMaxPriority(request.getUserId()) + 1;
            update.set("onTop", true);
            update.set("priority", priority);
        }
        update.setOnInsert("createdTime", new Date());
        update.set("updatedTime", new Date());
        update.setOnInsert("userId", request.getUserId());
        update.setOnInsert("activityId", request.getActivityId());
        mongoTemplate.findAndModify(query, update, UserActivityTopRecord.class);
        return true;
    }

    public int getMaxPriority(String userId) {
        // 获取最大优先级
        Query query1 = new Query().addCriteria(Criteria.where("userId").is(userId));
        query1.with(Sort.by("priority").descending());
        UserActivityTopRecord max = mongoTemplate.findOne(query1, UserActivityTopRecord.class);
        return max == null ? 0 : max.getPriority();
    }

    public List<UserActivityTopRecord> getActivityTopRecordList(String userId, List<String> aidList) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("onTop").is(true));
        query.addCriteria(Criteria.where("activityId").in(aidList));
        query.with(Sort.by("priority").descending());
        List<UserActivityTopRecord> record = mongoTemplate.find(query, UserActivityTopRecord.class);
        return record;
    }

    @Override
    public ActivityInfo query(String id) {
        log.info("查询活动信息开始，id:{}", id);
        ActivityInfo activityInfo = mongoTemplate.findById(id, ActivityInfo.class);
        if (activityInfo == null) {
            throw new BusinessException("活动信息查询失败!");
        }
        ActivityTaskRule activityTaskRule = activityTaskRuleService.find(id, TaskBizType.QA.name());
        if (Objects.nonNull(activityTaskRule)) {
            activityInfo.setAfterQaAddPoint(activityTaskRule.getPoints().intValue());
        }
        log.info("查询活动信息结束");
        return activityInfo;
    }

    private Long getUsetCount(String activityId, String userId) {
        UserDataPermission userDataPermission = null;
        if (StringUtils.isNotBlank(userId)) {
            UserDataPermission req = new UserDataPermission();
            req.setUserId(userId);
            List<UserDataPermission> datas = userDataPermissionService.list(req);
            if (!CollectionUtils.isEmpty(datas) && !CollectionUtils.isEmpty(datas.get(0).getActivityId())) {
                userDataPermission = datas.get(0);
                log.info(":>>> 用户:{} 的数据权限权限配置:{}", userId, userDataPermission == null ? 0 :
                        JSON.toJSON(userDataPermission.getActivityId()));
            }
        }
        Long count = userParticipateActivityInfoService.getJoinedCount(activityId);
        if (Objects.nonNull(userDataPermission) && Boolean.TRUE.equals(userDataPermission.getHasCardinalNumber())) {
            Double a =
                    Double.valueOf("" + (count - userDataPermission.getCardinalNumber())) * userDataPermission.getCardinalNumberRatio();
            count = userDataPermission.getCardinalNumber() + a.longValue();
        }
        Query q = new Query();
        q.addCriteria(Criteria.where("activityId").is(activityId));
        ActivitySimulationData a = mongoTemplate.findOne(q, ActivitySimulationData.class);
        if (Objects.nonNull(a)) {
            Double c = count * a.getCoefficient();
            count = c.longValue();
        }
        return count;
    }

    @Override
    public Page<UserParticipateActivityInfo> signUpList(ActivitySignQueryRequest request) {
        log.info("查询活动报名用户信息列表，参数:{}", JsonUtil.toJSON(request));
        ActivityInfo activityInfo = this.findOne(request.getActivityId());
        if (Objects.isNull(activityInfo)) {
            log.error(":>>> 活动不存在:{}", request.getActivityId());
            throw new BusinessException("活动不存在");
        }
        ActivityTaskInfo taskInfo = activityTaskService.find(request.getActivityId(), TaskBizType.INVITE);
        Query query = new Query();
        if (StringUtils.isNotBlank(request.getUniversityId())) {
            query.addCriteria(Criteria.where("universityId").is(request.getUniversityId()));
        }
        if (StringUtils.isNotBlank(request.getKey())) {
//            Pattern pattern = Pattern.compile("^.*" + request.getKey() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(new Criteria().orOperator(
                    Criteria.where("name").is(request.getKey()), Criteria.where("mobile").is(request.getKey())));
        }
        List<String> userIds = getParticiaptUserIds(request.getActivityId(), request.getTaskStatus(),
                request.getPageSize());
        if (!CollectionUtils.isEmpty(userIds)) {
            query.addCriteria(Criteria.where("userId").in(userIds));
        }
        //增加校赛分数查询，目前只支持微信小程序
        if (Objects.nonNull(request.getQaScore()) && request.getQaScore() > 0) {
            query.addCriteria(Criteria.where("qaScore").gte(request.getQaScore()));
        }
        query.addCriteria(Criteria.where("activityId").is(request.getActivityId()));
        if (!("60f8c919ff3415216ea74e82".equals(request.getActivityId()))) {
            log.info(":>>> 活动:{},不是:{}", request.getActivityId(), "60f8c919ff3415216ea74e82");
            query.addCriteria(Criteria.where("joined").is(Boolean.TRUE));
        }
        Criteria criteriaInvitedNum = null;
        if (request.getInvitedNumStart() != null || request.getInvitedNumEnd() != null) {
            criteriaInvitedNum = Criteria.where("invitedNum");
            if (request.getInvitedNumStart() != null) {
                criteriaInvitedNum.gte(request.getInvitedNumStart());
            }
            if (request.getInvitedNumEnd() != null) {
                criteriaInvitedNum.lte(request.getInvitedNumEnd());
            }
            query.addCriteria(criteriaInvitedNum);
        }
        long count = this.mongoTemplate.count(query, UserParticipateActivityInfo.class);
//        long count = userParticipateActivityInfoService.getJoinedCount(request.getActivityId());
//        if (count > 5000L) {
//            count = 5000L;
//        }
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        Long startDb = System.currentTimeMillis();
        List<UserParticipateActivityInfo> signUpUserList = new ArrayList<>();
        MongoCursor iterable =
                mongoTemplate.getCollection(mongoTemplate.getCollectionName(UserParticipateActivityInfo.class)).find(query.getQueryObject()).limit(request.getPageSize()).skip((request.getPage() - 1) * request.getPageSize()).
                        noCursorTimeout(true).sort(query.getSortObject()).batchSize(request.getPageSize()).iterator();
        log.info(":>>> 活动:{} 游标耗时:{} 毫秒", request.getActivityId(), System.currentTimeMillis() - startDb);

        UserParticipateActivityInfo u = null;
        Document o = null;
        UserParticipateActivityInfo r = null;
        while (iterable.hasNext()) {
            o = (Document) iterable.next();
            if (Objects.nonNull(o)) {
                r = new UserParticipateActivityInfo();
                if (StringUtils.isNotBlank(o.getString("id"))) {
                    r.setId(o.getString("id"));
                } else {
                    r.setId(o.getObjectId("_id").toString());
                }
                r.setName(o.getString("name"));
                r.setMobile(o.getString("mobile"));
                r.setOpenId(o.getString("openId"));
                r.setUniversityName(o.getString("universityName"));
                r.setUniversityId(o.getString("universityId"));
                r.setActivityId(o.getString("activityId"));
                r.setQaScore(o.getDouble("qaScore"));
                r.setProvinceQaScore(o.getDouble("provinceQaScore"));
                r.setCountryQaScore(o.getDouble("countryQaScore"));
                r.setInBlackList(o.getBoolean("inBlackList"));
                r.setSignUpTime(o.getDate("signUpTime"));
                r.setUserId(o.getString("userId"));
                r.setJoinRank(o.getBoolean("joinRank"));
                r.setRankAvatarUrl(o.getString("rankAvatarUrl"));
                r.setRankNickName(o.getString("rankNickName"));
                r.setEnName(o.getString("enName"));
                r.setActivityChannelId(o.getString("activityChannelId"));
                r.setUserId(o.getString("userId"));
                r.setActivityId(o.getString("activityId"));
                r.setUnionId(o.getString("unionId"));
                r.setUserSignInDay(o.getInteger("userSignInDay"));
                signUpUserList.add(r);
            }
        }
        try {
            for (UserParticipateActivityInfo userParticipateActivityInfo : signUpUserList) {
                if (request.getMobileHide()) {//手机号是否要脱敏
                    userParticipateActivityInfo.setMobile("");
                } else {
                    if (request.getMobileDesensitization()) {//手机号是否要脱敏
                        userParticipateActivityInfo.setMobile(userParticipateActivityInfo.getMobile().replaceAll(MOBILE_REGEX, "$1****$2"));
                    }
                }
                if (Boolean.TRUE.equals(activityInfo.getHasMultiQa())) {
                    Query query1 =
                            new Query().addCriteria(Criteria.where("userId").is(userParticipateActivityInfo.getUserId()).
                                    and("activityId").is(userParticipateActivityInfo.getActivityId()));
                    List<UserQaInfo> userQaInfos = mongoTemplate.find(query1, UserQaInfo.class);
                    if (!CollectionUtils.isEmpty(userIds)) {
                        for (UserQaInfo userQaInfo : userQaInfos) {
                            if (Objects.nonNull(userQaInfo.getNo())) {
                                switch (userQaInfo.getNo().intValue()) {
                                    case 1:
                                        userParticipateActivityInfo.setQaScore(userQaInfo.getQaScore());
                                        break;
                                    case 2:
                                        userParticipateActivityInfo.setProvinceQaScore(userQaInfo.getQaScore());
                                        break;
                                    case 3:
                                        userParticipateActivityInfo.setCountryQaScore(userQaInfo.getQaScore());
                                        break;
                                    default:
                                        break;
                                }
                            }

                        }

                    }
                }
                Double q = 0.0D;
                if ("contest-plus".equals(activityInfo.getType()) || "qq-mini-plus-noncontest".equals(activityInfo.getType()) || "h5++".equals(activityInfo.getType())) {
                    UserActivityPointRanking ranking =
                            userActivityPointRankingService.find(userParticipateActivityInfo.getUserId(), "",
                                    userParticipateActivityInfo.getActivityId());
                    if (Objects.nonNull(ranking)) {
                        q = ranking.getQuantity();
                        userParticipateActivityInfo.setCurrentQ(q);
                    }
                } else {
                    List<String> uids = visitorUserService.findCorrentUserId(userParticipateActivityInfo.getUserId());
                    q = activityServiceS.getTaskQuantityByUids(userParticipateActivityInfo.getActivityId(),
                            taskInfo.getId(), uids);
                    userParticipateActivityInfo.setCurrentQ(q);

                }
            }

        } catch (Exception e) {
            log.error(":>>> 设置答题错误:{}", e);
        }
        final Long total = count;
        return PageableExecutionUtils.getPage(signUpUserList, pageRequest, () -> total);
    }

    @Override
    public Page<UserActivityFootPrint> footPrintList(ActivityFootPrintQueryVO req) {
        log.info(":>>> 开始获取足迹列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || StringUtils.isBlank(req.getUserId())) {
            log.error(":>>> 获取用户足迹参数错误");
            throw new BusinessException("获取用户足迹参数错误");
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(req.getActivityId()).and("userId").is(req.getUserId()));
        if (StringUtils.isNotBlank(req.getTaskBizType())) {
            if ("NULL".equals(req.getTaskBizType())) {
                query.addCriteria(Criteria.where("taskBizType").is(null));
            } else {
                query.addCriteria(Criteria.where("taskBizType").is(req.getTaskBizType()));
            }
        }
        if (Objects.nonNull(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        Long count = mongoTemplate.count(query, UserActivityFootPrint.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserActivityFootPrint> signUpUserList = mongoTemplate.find(query.with(pageRequest),
                UserActivityFootPrint.class);
        return PageableExecutionUtils.getPage(signUpUserList, pageRequest, () -> count);
    }

    @Override
    public Page<UserActivityFootPrint> imageListPrint(ActivityFootPrintQueryVO req) {
        log.info(":>>> 开始获取足迹图片列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取用户足迹参数错误");
            throw new BusinessException("获取用户足迹参数错误");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        if (StringUtils.isNotBlank(req.getTaskBizType())) {
            if ("NULL".equals(req.getTaskBizType())) {
                query.addCriteria(Criteria.where("taskBizType").is(null));
            } else {
                query.addCriteria(Criteria.where("taskBizType").is(req.getTaskBizType()));
            }
        }
        if (Objects.nonNull(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        if (StringUtils.isNotBlank(req.getAppId())) {
            query.addCriteria(Criteria.where("appId").is(req.getAppId()));
        }
        if (StringUtils.isNotBlank(req.getPlatform())) {
            query.addCriteria(Criteria.where("platform").is(req.getPlatform()));
        }
        if (StringUtils.isNotBlank(req.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
        }
        Long count = mongoTemplate.count(query, UserActivityFootPrint.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserActivityFootPrint> signUpUserList = mongoTemplate.find(query.with(pageRequest),
                UserActivityFootPrint.class);
        if (!CollectionUtils.isEmpty(signUpUserList)) {
            HashMap<String, ActivityInfo> activityInfoHashMap = new HashMap<>();
            HashMap<String, ActivityTaskInfo> activityTaskInfoHashMap = new HashMap<>();
            for (UserActivityFootPrint userActivityFootPrint : signUpUserList) {
                ActivityInfo activityInfo = null;
                if (activityInfoHashMap.containsKey(userActivityFootPrint.getActivityId())) {
                    activityInfo = activityInfoHashMap.get(userActivityFootPrint.getActivityId());
                } else {
                    activityInfo = activityServiceS.findOne(userActivityFootPrint.getActivityId());
                    if (Objects.nonNull(activityInfo)) {
                        activityInfoHashMap.put(userActivityFootPrint.getActivityId(), activityInfo);
                    }
                }
                if (Objects.nonNull(activityInfo)) {
                    userActivityFootPrint.setActivityName(activityInfo.getName());
                }
                ActivityTaskInfo activityTaskInfo = null;
                if (activityTaskInfoHashMap.containsKey(userActivityFootPrint.getTaskId())) {
                    activityTaskInfo = activityTaskInfoHashMap.get(userActivityFootPrint.getTaskId());
                } else {
                    activityTaskInfo = activityTaskService.findOne(userActivityFootPrint.getTaskId());
                    if (Objects.nonNull(activityTaskInfo)) {
                        activityTaskInfoHashMap.put(userActivityFootPrint.getTaskId(), activityTaskInfo);
                    }
                }
                if (Objects.nonNull(activityTaskInfo)) {
                    userActivityFootPrint.setApproveType(activityTaskInfo.getApproveType());
                }
            }
        }
        return PageableExecutionUtils.getPage(signUpUserList, pageRequest, () -> count);
    }

    @Override
    public void updateActivityOrg(ActivityOrgReq activityOrgReq) {
        String id = activityOrgReq.getId();
        log.info(" 活动 -> {} 组织单位配置", activityOrgReq.getId());
        ActivityInfo activityInfo = this.mongoTemplate.findById(id, ActivityInfo.class);
        if (Objects.isNull(activityInfo)) {
            throw new BusinessException("活动不存在!");
        }
        Set<ActivityCaOrg> activityCaOrgSet = activityOrgReq.getActivityCaOrgSet();
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("activityCaOrgSet", activityCaOrgSet);
        update.set("updatedTime", new Date());
        this.cacheActivityService.remove(id);
        this.mongoTemplate.updateFirst(query, update, ActivityInfo.class);
    }

    @Override
    public boolean updateUserInfo(UserParticipateActivityInfo req) {
        log.info(":>>> 开始修改报名信息:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId())) {
            log.error(":>>> 修改用户报名信息参数错误");
            throw new BusinessException("修改用户报名信息参数错误");
        }

        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));

        UserParticipateActivityInfo exist = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.isNull(exist)) {
            log.error(":>>> 数据不存在:{}", req.getId());
            throw new BusinessException("数据不存在");
        }
        ActivityInfo activityInfo = this.findOne(exist.getActivityId());
        Update update = new Update();
        if (StringUtils.isNotBlank(req.getName())) {
            update.set("name", req.getName());
        }
        if (StringUtils.isNotBlank(req.getEnName())) {
            update.set("enName", req.getEnName());
        }
        if (StringUtils.isNotBlank(req.getMobile())) {
            update.set("mobile", req.getMobile());
        }
        if (StringUtils.isNotBlank(req.getGrade())) {
            update.set("grade", req.getGrade());
        }
        if (StringUtils.isNotBlank(req.getQq())) {
            update.set("qq", req.getQq());
        }
        if (Objects.nonNull(req.getQaScore())) {
            update.set("qaScore", req.getQaScore());
            userQaInfoService.updateByQaNo(req.getUserId(), req.getActivityId(), 1, req.getQaScore());
        }
        if (Objects.nonNull(req.getProvinceQaScore())) {
            update.set("provinceQaScore", req.getProvinceQaScore());
            userQaInfoService.updateByQaNo(req.getUserId(), req.getActivityId(), 2, req.getQaScore());
        }
        if (Objects.nonNull(req.getCountryQaScore())) {

            update.set("countryQaScore", req.getCountryQaScore());
            userQaInfoService.updateByQaNo(req.getUserId(), req.getActivityId(), 3, req.getQaScore());
        }
        if (StringUtils.isNotBlank(req.getUniversityId())) {
            update.set("universityId", req.getUniversityId());
            UniversityInfo universityInfo = universityInfoService.findOne(req.getUniversityId());
            if (Objects.nonNull(universityInfo)) {
                update.set("universityName", universityInfo.getName());
            }
        }
        UserPO userPO1 = visitorUserService.getUser(exist.getUserId());
        if (Objects.nonNull(userPO1)) {
            userPO1.setRankNickName(req.getRankNickName());
            userPO1.setRankAvatarUrl(req.getRankAvatarUrl());
            visitorUserService.updateUserPo(userPO1, exist.getPlatform(), exist.getAppId());
        }
        if (StringUtils.isNotBlank(req.getRankNickName())) {
            update.set("rankNickName", req.getRankNickName());
        }
        if (StringUtils.isNotBlank(req.getRankAvatarUrl())) {
            update.set("rankAvatarUrl", req.getRankAvatarUrl());
        }
        // 设置用户排行榜黑名单,控制用户是否在排行榜上显示
        if (Objects.nonNull(req.getJoinRank())) {
            update.set("joinRank", req.getJoinRank());
            if (Boolean.FALSE.equals(req.getJoinRank())) {
                boolean hasBlack = userRankBlackListService.exist(exist.getUserId(), exist.getActivityId());
                if (!hasBlack) {
                    UserRankBlackList userRankBlackList = new UserRankBlackList();
                    userRankBlackList.setUserId(exist.getUserId());
                    userRankBlackList.setActivityId(exist.getActivityId());
                    userRankBlackListService.create(userRankBlackList);
                }
            } else {
                userRankBlackListService.delete(exist.getUserId(), exist.getActivityId());
            }
        }
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserParticipateActivityInfo.class);
        log.info(":>>> 修改用户报名信息:{} 结果:{}", req.getId(), updateResult.getModifiedCount() > 0 ? true : false);
        if (Objects.nonNull(req.getQuantity())) {
            ActivityTaskInfo taskInfo = activityServiceS.getTaskInfo(exist.getActivityId(), TaskBizType.INVITE);
            if (Objects.isNull(taskInfo) && req.getQuantity().compareTo(0D) == 0) {
                log.error(":>>> 活动:{} 任务信息不存在,贡献值为0");
                return true;
            }
            if (!("h5-plus".equals(activityInfo.getType()) || "vote".equals(activityInfo.getType()) || "video".equals(activityInfo.getType()) || "qq-mini-plus-noncontest".equals(activityInfo.getType()) || "qq-mini-plus".equals(activityInfo.getType())
                    || "contest-plus".equals(activityInfo.getType()) || "qq-mini-zhongqing-contest".equals(activityInfo.getType()) || "h5++".equals(activityInfo.getType()))) {
                log.info(":>>> 活动:{} 是老版本,修改贡献值为:{},userId:s{}", activityInfo.getName(), req.getQuantity(),
                        exist.getUserId());
                UserParticipateActivityTaskInfo userParticipateActivityTaskInfo =
                        new UserParticipateActivityTaskInfo();
                userParticipateActivityTaskInfo.setActivityId(req.getActivityId());
                userParticipateActivityTaskInfo.setTaskId(taskInfo.getId());
                userParticipateActivityTaskInfo.setBizType(TaskBizType.INVITE);
                userParticipateActivityTaskInfo.setQuantity(req.getQuantity());
                // 操纵类型0:累加,1:替换
                // 更新总榜单
                UserPO userPO = visitorUserService.getUser(exist.getUserId());
                activityServiceS.updateUserTaskAllRanking(userPO, userParticipateActivityTaskInfo,
                        0);
                update = new Update();
                update.set("importQuantityAdd", Boolean.TRUE);
                this.mongoTemplate.updateMulti(query, update, UserParticipateActivityInfo.class);
            } else {
                // 积分类
                log.info(":>>> 活动:{} 是新版本,修改贡献值为:{},userId:s{}", activityInfo.getName(), req.getQuantity(),
                        exist.getUserId());
                UserActivityPointDetail detail = new UserActivityPointDetail();
                detail.setActivityId(activityInfo.getId());
                detail.setUserId(exist.getUserId());
                detail.setUserPO(userPO1);
                detail.setPoints(req.getQuantity().intValue());
                detail.setAction("add");
                detail.setBizDesc("其他任务");
                detail.setBizType("other");
                userActivityPointDetailService.create(detail);
                userActivityPointRankingProvinceService.updatePoint(userPO1, activityInfo.getId(),
                        req.getQuantity().intValue());

            }


        }
        if (updateResult.getModifiedCount() > 0) {
            //更新渠道报名用户
            this.updateDistributorChannelUserInfo(req);
        }
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean blackList(UserParticipateActivityInfo req, String optUser) {
        log.info(":>>> 开始将用户加入黑名单:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId())) {
            log.error(":>>> 将用户加入黑名单参数错误");
            throw new BusinessException("将用户加入黑名单");
        }
        String userId = "";
        String name = "";
        String mobile = "";
        UpdateResult updateResult = null;
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        UserParticipateActivityInfo exist = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.nonNull(exist)) {
            userId = exist.getUserId();
            mobile = exist.getMobile();
            name = exist.getName();
            Update update = new Update();
            update.set("inBlackList", Boolean.TRUE);
            update.set("deleted", Boolean.TRUE);
            update.set("updatedTime", new Date());
            updateResult = mongoTemplate.updateFirst(query, update, UserParticipateActivityInfo.class);
        } else {
            JinUserParticipate jinUser = this.mongoTemplate.findById(req.getId(), JinUserParticipate.class);
            if (Objects.nonNull(jinUser)) {
                userId = jinUser.getUserId();
                mobile = jinUser.getMobile();
                name = jinUser.getName();
                Update update = new Update();
                update.set("inBlackList", Boolean.TRUE);
                update.set("deleted", Boolean.TRUE);
                update.set("updatedTime", new Date());
                updateResult = mongoTemplate.updateFirst(query, update, JinUserParticipate.class);
            }
        }
        if (StringUtils.isNotBlank(userId)) {
            boolean in = blackListService.exist(userId);
            if (!in) {
                UserBlackList userBlackList = new UserBlackList();
                userBlackList.setUserId(userId);
                userBlackList.setName(name);
                userBlackList.setStatus(true);
                userBlackList.setMobile(mobile);
                userBlackList.setOptUser(optUser);
                userBlackList.setDesc("运营加入黑名单");
                mongoTemplate.insert(userBlackList);
            }
        }
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public UserParticipateActivityInfo findOnesignUpUser(String id) {
        log.info(":>>> 开始查询用户报名信息:{}", id);
        if (StringUtils.isBlank(id)) {
            log.error(":>>> 查询用户报名信息参数错误");
            throw new BusinessException("查询用户报名信息参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        UserParticipateActivityInfo up = mongoTemplate.findOne(query, UserParticipateActivityInfo.class);
        if (Objects.isNull(up)) {
            log.error(":>>> 查询用户:{} 报名信息不存在", id);
            throw new BusinessException("查询用户报名信息不存在");
        }
        ActivityInfo activityInfo = this.findOne(up.getActivityId());
        ActivityTaskInfo taskInfo = activityServiceS.getTaskInfo(up.getActivityId(), TaskBizType.INVITE);
        Double q = 0.0D;
        if (Boolean.TRUE.equals(activityInfo.getHasPoint())
                &&
                ("contest-plus".equals(activityInfo.getType())
                        || ("qq-mini-plus-noncontest").equals(activityInfo.getType())
                        || "h5++".equals(activityInfo.getType())
                )) {
            UserActivityPointRanking ranking = userActivityPointRankingService.find(up.getUserId(), "",
                    up.getActivityId());
            if (Objects.nonNull(ranking)) {
                q = ranking.getQuantity();
                up.setQuantity(q);
                up.setCurrentQ(q);
                log.info(":>>> 用户:{} 活动:{} 积分排行榜积分:{}", up.getUserId(), id, q);
            } else {
                up.setQuantity(q);
                up.setCurrentQ(q);
            }
        } else {
            List<String> uids = visitorUserService.findCorrentUserId(up.getUserId());
            q = activityServiceS.getTaskQuantityByUids(up.getActivityId(), taskInfo.getId(), uids);
            up.setQuantity(q);
            up.setCurrentQ(q);

        }
        Query queryInvite =
                new Query().addCriteria(Criteria.where("invitedByUserId").is(up.getUserId()).and("taskId").is(taskInfo.getId()));
        List<UserInviteRecord> records = mongoTemplate.find(queryInvite, UserInviteRecord.class);
        if (CollectionUtils.isEmpty(records)) {
            up.setInviteTotalNum(0);
            up.setInviteSuccessNum(0);
        } else {
            up.setInviteTotalNum(records.size());
            Integer c = 0;
            for (UserInviteRecord u : records) {
                if (Boolean.TRUE.equals(u.getJoinStatus())) {
                    c++;
                }
            }
            up.setInviteSuccessNum(c);
        }
        return up;
    }

    @Override
    public String generateShortUrl(String id, String urlType) {
        log.info(":>>> 开始生成短链接:{}", id);
        if (StringUtils.isBlank(id)) {
            log.error(":>>> 活动ID为空");
            throw new BusinessException("活动ID为空");
        }
        PlatformConfig platformConfig = platformConfigService.find();
        ActivityInfo activityInfo = findOne(id);
        String domain = "";
        String catalogue = "";
        String type = "";
        boolean newLinker = false;
        // 竞赛类的活动
        if (constentActivity.contains(id)) {
            domain = platformConfigService.getContestBizFrontDomain();
            catalogue = platformConfigService.getContestCatalogue();
            type = "C";
        } else {
            domain = platformConfigService.getBizFrontDomain();
            if ("contest-plus".equals(activityInfo.getType())) {
                catalogue = platformConfigService.getContestPlusCatalogue();
                type = "C-PLUS";
            } else if ("vote".equals(activityInfo.getType())) {
                catalogue = platformConfigService.getVoteCatalogue();
                type = "A";
            } else {
//               catalogue = platformConfigService.getCatalogue();
                type = "A";
                newLinker = true;
                // 2022-10-27 10:33:55的毫秒数:1666838035000L
                Integer hours = TimeUtils.getHours(new Date(1666838035000L), new Date());
                // 更新当前目录下标
                log.info(":>>> 当前时间:{} 小时数:{},当前目录标号:{}", new Date(), hours, platformConfig.getCurrentCatalogue());
                if (hours.compareTo(platformConfig.getCurrentCatalogue()) != 0) {
                    platformConfigService.updateCurrentCatalogue(platformConfig.getId(), hours);
                }
                catalogue = String.format(platformConfig.getMainCataloguePrefix(), (platformConfig.getMainCatalogueMin() + hours));
                log.info(":>>> 生成的活动:{} 目录为:{}", id, catalogue);
            }
        }
        String wechatUrl = this.getWechatUrl(activityInfo, type);
//        wechatUrl = platformConfigService.replaceActiveCatalogue(wechatUrl, catalogue, type);
        log.info(":>>> 活动:{},类型:{} 对应的链接为:{}", activityInfo.getId(), type, wechatUrl);
        String u = String.format(wechatUrl, domain, "%s");
        if ("jinshuju".equals(activityInfo.getType())) {
            catalogue = platformConfig.getJinCatalogue();
            long time = System.currentTimeMillis();
            type = "J";
            domain = platformConfig.getJinBizFrontDomain();
            String activityId = activityInfo.getId();
            if ("2".equals(urlType)) {
                String searchPath = "/index.html?a=1#/pages/search?scope=snsapi_base&activityId=" + activityId + "&t=" + time + "&appId=" + activityInfo.getWechatAppId();
                u = domain + catalogue + searchPath;
            } else {
                String joinPath = "/index.html?a=1#/pages/index?scope=snsapi_base&activityId=" + activityId + "&t=" + time + "&appId=" + activityInfo.getWechatAppId();
                u = domain + catalogue + joinPath;
            }
        }
        String shortUrl = ShotUrlUtil.shortUrl(u);
        if (!huoLinkerInfoService.exist(shortUrl)) {
            HuoLinkerInfo huoLinkerInfo = new HuoLinkerInfo();
            huoLinkerInfo.setActivityId(activityInfo.getId());
            huoLinkerInfo.setBizType(type);
            huoLinkerInfo.setDomain(domain);
            huoLinkerInfo.setCreatedTime(new Date());
            huoLinkerInfo.setUrl(u);
            huoLinkerInfo.setKey(shortUrl);
            huoLinkerInfo.setCatalogue(catalogue);
            huoLinkerInfo.setVersion("V2");
            huoLinkerInfoService.create(huoLinkerInfo);
        }
        log.info(":>>> 活动:{} 短链接地址为:{},对应长链接:{}", id, shortUrl, u);
        return shortUrl;
    }

    @Override
    public Page<ActivityResponse> newActivityList(ActivityQueryRequest request) {
        log.info(":>>> 活动列表新接口:{}", JSON.toJSONString(request));
        Query query = new Query();
        if (StringUtils.isNotBlank(request.getName())) {
            Pattern pattern = Pattern.compile("^.*" + request.getName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("name").regex(pattern));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        UserDataPermission userDataPermission = null;
        if (Boolean.FALSE.equals(request.getAll()) && StringUtils.isNotBlank(request.getUserId())) {
            UserDataPermission req = new UserDataPermission();
            req.setUserId(request.getUserId());
            List<UserDataPermission> datas = userDataPermissionService.list(req);
            if (!CollectionUtils.isEmpty(datas) && !CollectionUtils.isEmpty(datas.get(0).getActivityId())) {
                userDataPermission = datas.get(0);
                log.info(":>>> 用户:{} 的数据权限权限配置:{}", request.getUserId(),
                        JSON.toJSON(userDataPermission.getActivityId()));
                query.addCriteria(Criteria.where("id").in(datas.get(0).getActivityId()));
            }
        }
        Long count = mongoTemplate.count(query, ActivityInfo.class);
        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<ActivityInfo> activityInfos = mongoTemplate.find(query.with(pageRequest), ActivityInfo.class);
        List<ActivityResponse> list = activityInfos.stream().map(activityInfo -> {
            ActivityResponse response = mapperFacade.map(activityInfo, ActivityResponse.class);
            setSignUpData(response, activityInfo);
            return response;
        }).collect(Collectors.toList());
        log.info(":>>> 活动列表:{}", list == null ? 0 : list.size());
        Long finalCount = count;
        return PageableExecutionUtils.getPage(list, pageRequest, () -> finalCount);
    }

    @Override
    public void setJoinedCount(String id) {
        Query query = new Query();
        if (StringUtils.isNotBlank(id)) {
            query.addCriteria(Criteria.where("id").is(id));
        }
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        List<ActivityInfo> activityInfos = mongoTemplate.find(query, ActivityInfo.class);
        for (ActivityInfo activityInfo : activityInfos) {
            log.info(":>>> 开始更新活动:{} 报名人数", activityInfo.getId());
            Query query1 =
                    new Query().addCriteria(Criteria.where("activityId").is(activityInfo.getId()).and("joined").is(Boolean.TRUE));
            Long count = mongoTemplate.count(query1, UserParticipateActivityInfo.class);
            userParticipateActivityInfoService.increJoinedCount(activityInfo.getId(), count);
            log.info(":>>> 结束更新活动:{} 报名人数:{}", activityInfo.getId(), count);
        }
    }

    @Override
    public boolean updateUserPermission(UserDataPermissionUpdateVO request) {
        if (Objects.isNull(request) || StringUtils.isBlank(request.getActivityId()) || CollectionUtils.isEmpty(request.getUserIds())) {
            return false;
        }
        return userDataPermissionService.addUserDataPermission(request.getActivityId(), request.getUserIds());
    }

    @Override
    public UserDataPermission getUserPermission(String id) {
        log.info(":>>> 获取活动用户角色:{}", id);
        if (StringUtils.isBlank(id)) {
            log.error(":>>> 活动ID为空");
            throw new BusinessException("活动ID为空");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(id));
        List<UserDataPermission> userDataPermissions = mongoTemplate.find(query, UserDataPermission.class);
        if (CollectionUtils.isEmpty(userDataPermissions)) {
            UserDataPermission userDataPermission = new UserDataPermission();
            return userDataPermission;
        }
        UserDataPermission userDataPermission = new UserDataPermission();
        for (UserDataPermission u : userDataPermissions) {
            if (StringUtils.isNotBlank(u.getUserId())) {
                Query query1 = new Query().addCriteria(Criteria.where("id").is(u.getUserId()));
                SystemUser systemUser = mongoTemplate.findOne(query1, SystemUser.class);
                if (Objects.nonNull(systemUser)) {
                    HashMap<String, String> to = new HashMap<>();
                    to.put("id", systemUser.getId());
                    to.put("name", systemUser.getRealName());
                    to.put("loginName", systemUser.getLoginName());
                    userDataPermission.getUsers().add(to);
                }
            }

        }
        return userDataPermission;
    }

    @Override
    public HashMap<String, Double> getRankInfo(String userId, String activityId) {
        log.info(":>>> 开始获取排行榜的值:{},activityId:{}", userId, activityId);
        UserParticipateActivityInfo up = userParticipateActivityInfoService.findBy(activityId, userId);
        if (Objects.isNull(up)) {
            return new HashMap<>();
        }
        HashMap<String, Double> res = new HashMap<>();
        ActivityTaskInfo taskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        String key = userRankListService.getAllRankCountryKey(activityId, taskInfo.getId());
        Double q = rankBaseService.getSingleRankScore(key, userId);
        res.put("country", q);
        String p = visitorUserService.getUserProvince(activityId, userId);
        String keyProvince = userRankListService.getAllRankProvinceKey(activityId, taskInfo.getId(), p);
        Double qProvince = rankBaseService.getSingleRankScore(keyProvince, userId);
        res.put("province", qProvince);
        List<String> uids = new ArrayList<>();
        uids.add(userId);
        Double db = activityServiceS.getTaskQuantityByUids(activityId, taskInfo.getId(), uids);
        res.put("dbQ", db);
        return res;
    }

    @Override
    public boolean updateRankInfo(String userId, String activityId, Double q) {
        log.info(":>>> 开始修改用户:{},活动:{} 排行榜信息:{}", userId, activityId, q);
        UserParticipateActivityInfo up = userParticipateActivityInfoService.findBy(activityId, userId);
        if (Objects.isNull(up)) {
            return false;
        }
        ActivityTaskInfo taskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
        String key = userRankListService.getAllRankCountryKey(activityId, taskInfo.getId());
        rankBaseService.addSingleRank(key, userId, q);
        String p = visitorUserService.getUserProvince(activityId, userId);
        String keyProvince = userRankListService.getAllRankProvinceKey(activityId, taskInfo.getId(), p);
        rankBaseService.addSingleRank(keyProvince, userId, q);
        return true;
    }

    @Autowired
    private RoleService roleService;

    @Override
    public QResult transferCreator(String activityId, String newCreatorId) {
        log.info(":>>> 开始转移活动创建者activityId:{},newCreatorId:{}", activityId, newCreatorId);
        ActivityInfo activityInfo = this.findOne(activityId);
        if (newCreatorId.equals(activityInfo.getCreatorId())) {
            return QResult.success(true);
        }
        String userId = AuthUtils.getUserId();
        List<SystemRole> roleList = roleService.findAllByUserId(userId);
        List<SystemRole> adminRole = roleList.stream().filter(r -> "admin".equals(r.getIdentifier())).collect(Collectors.toList());
        //判断是否是 管理员  或者 是不是创建者
        if (CollectionUtils.isEmpty(adminRole) && !userId.equals(activityInfo.getCreatorId())) {
            return QResult.fail("你无当前活动相关权限");

        }
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(activityId));
        Update update = new Update();
        update.set("creatorId", newCreatorId);
        update.set("updatedTime", new Date());
        boolean b = mongoTemplate.updateFirst(query, update, ActivityInfo.class).getModifiedCount() > 0 ? true : false;
        return QResult.success(b);
    }

    private ActivityInfo findOne(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        ActivityInfo activityInfo = mongoTemplate.findOne(query, ActivityInfo.class);
        if (activityInfo == null) {
            throw new BusinessException("活动信息查询失败!");
        }
        return activityInfo;
    }

    /**
     * 获取用户足迹响应状态的用户ID
     *
     * @param activityId
     * @param status
     * @return
     */
    private List<String> getParticiaptUserIds(String activityId, Integer status, Integer limit) {
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId));
        if (Objects.isNull(status)) {
            return new ArrayList<>();
        }
        /**
         * 状态,0:待审核,1:审核通过,2:驳回,3:无提交
         */
        query.addCriteria(Criteria.where("status").is(status));
        query.limit(limit);
        List<String> datas = mongoTemplate.findDistinct(query, "userId", UserActivityFootPrint.class, String.class);
        if (CollectionUtils.isEmpty(datas)) {
            return new ArrayList<>();
        }
        return datas;
    }

    /**
     * 获取微信链接
     *
     * @param activityInfo
     * @return
     */
    private String getWechatUrl(ActivityInfo activityInfo, String type) {
        switch (type) {
            case "A":
                String wechatUrl1 = String.format(this.activityUrl, activityInfo.getId(),
                        activityInfo.getWechatAppId(), activityInfo.getThemeColor(), activityInfo.getAuthorizeMode()) + "&timestamp=" + System.currentTimeMillis();
                return "%s/%s" + wechatUrl1;
            case "C":
                String wechatUrl = String.format(this.activityContestUrl, activityInfo.getWechatAppId(),
                        activityInfo.getId()) + "&timestamp=" + System.currentTimeMillis();
                return "%s" + wechatUrl;
            case "C-PLUS": {
                String wechatUrlP = String.format(this.activityContestPluUrl, activityInfo.getWechatAppId(),
                        activityInfo.getId(), activityInfo.getThemeColor()) + "&timestamp=" + System.currentTimeMillis();
                return "%s" + wechatUrlP;
            }
            default:
                break;
        }
        return "";
    }

    /**
     * 设置学习签到参数
     *
     * @param response
     * @param activityInfo
     */
    private void setSignUpData(ActivityResponse response, ActivityInfo activityInfo) {
        try {
            if (Boolean.FALSE.equals(activityInfo.getHasSignIn())) {
                return;
            }
            if (Objects.isNull(activityInfo.getStartTime()) || Objects.isNull(activityInfo.getEndTime())) {
                return;
            }
            Integer total = TimeUtils.getDiffDays(activityInfo.getStartTime(), activityInfo.getEndTime());
            response.setTotalSignUpDays(total);
            Query query = new Query().addCriteria(Criteria.where("activityId").is(activityInfo.getId()));
            // 已经配置
            Long count = mongoTemplate.count(query, DailyLearning.class);
            response.setNoConfigSignedUpDays(total - count.intValue());
            Integer already = TimeUtils.getDiffDays(activityInfo.getStartTime(), new Date());
            response.setSignedUpDays(already);
            if (already > count.intValue()) {
                response.setSignUpConfigAlarm(true);
            }
        } catch (Exception e) {
            log.error(":>>> 设置签到天数错误:{}", e);
        }


    }

    private void updateDistributorChannelUserInfo(UserParticipateActivityInfo req) {
        if (StringUtils.isBlank(req.getActivityChannelId())) {
            return;
        }
        UserParticipateDistributorChannelInfo updateDistributorChannelInfo = mapperFacade.map(req, UserParticipateDistributorChannelInfo.class);
        updateDistributorChannelInfo.setId(null);
        userParticipateDistributorChannelInfoService.save(updateDistributorChannelInfo);
    }

}
